<HTML><HEAD><TITLE>read_annotated(+Stream, -Term, -AnnTerm)</TITLE>
</HEAD><BODY>[ <A HREF="index.html">Term I/O</A> | <A HREF="../../index.html">Reference Manual</A> | <A HREF="../../fullindex.html">Alphabetic Index</A> ]
<H1>read_annotated(+Stream, -Term, -AnnTerm)</H1>
Read term with type and source position information
<DL>
<DT><EM>Stream</EM></DT>
<DD>Integer (stream number) or Atom (reserved or user-defined symbolic stream name).
</DD>
<DT><EM>Term</EM></DT>
<DD>Variable or term
</DD>
<DT><EM>AnnTerm</EM></DT>
<DD>Variable or term
</DD>
</DL>
<H2>Description</H2>
<P>    Reads the next input term (up to the end of file, or up to a fullstop)
    from from the input stream Stream, and returns this term as Term, and
    a descriptor AnnTerm.  AnnTerm is structurally similar to Term and
    contains all information about the term, plus additional type information,
    variable names, and source position annotations for all subterms.
</P><P>
    The structure of the descriptive terms is as follows:
    <PRE>
	:- export struct(annotated_term(
		term,			% var, atomic or compound
		type,			% term type (see below)
		file,			% source file name (atom)
		line,			% source line (integer)
		from, to		% source position (integers)
		...
	)).
    </PRE>
</P><P>
    The type-field describes the type of the parsed term and is one of
    the following:
<PRE>
    integer
    float
    rational
    breal
    atom
    string
    compound		term is compound (with annotated subterms)
    anonymous		term is a variable (was anonymous (_) in source)
    var(NameAtom)	term is a variable (with the given source name)
    var			term is a variable (introduced by macro expansion)
    end_of_file		end of file was read (term is end_of_file)
</PRE>
    These type names correspond to the ones used in type_of/2, except that
    they convey additional information about variables and end_of_file..
</P><P>
    In the case of atomic terms and variables, the term-field simply
    contains the plain parsed term. For compound terms, the term-field
    contains a structure whose functor is the functor of the plain term,
    but whose arguments are annotated versions of the plain term arguments.
</P><P>
    E.g. the source term
<PRE>
	3
</PRE>
    is parsed as
<PRE>
	annotated_term(3, integer, ...)
</PRE>
</P><P>
    The source term
<PRE>
	foo(bar, X, _, 3)
</PRE>
    is parsed as
<PRE>
	annotated_term(foo(
	    annotated_term(bar, atom, ...),
	    annotated_term(X, var('X'), ...),
	    annotated_term(_, anonymous, ...),
	    annotated_term(3, integer, ...)),
	compound, ...)
</PRE>
</P><P>
    The source term
<PRE>
	[1,2]
</PRE>
    is parsed as
<PRE>
	annotated_term(.(
	    annotated_term(1, integer, ...),
		annotated_term(.(
			annotated_term(2, integer, ...),
			annotated_term([], atom, ...)),
		    compound, ...)),
	    compound, ...)
</PRE>
</P><P>
The file/line/from/to-fields of an annotated term describe the
"source position" of the term.  The fields contain:
<DL>
<DT>file</DT><DD>
    The canonical file name of the source file (an atom), or the
    empty atom '' if the source is not a file or not known.
</DD>
<DT>line</DT><DD>
    The line number in the source stream (positive integer).
</DD>
<DT>from, to</DT><DD>
    The exact term position as integer offsets in the source stream,
    starting at from and ending at to-1.
</DD>
</DL>
The source position of a whole (sub)term is defined as the source position
of the unique token (sometimes token pair) which represents that (sub)term.
The representing token (pair) is defined as follows:
<UL>
<LI>atoms, strings and unsigned numbers are represented by their
    corresponding IDENTIFIER, NUMBER or STRING token.

<LI>signed numbers are represented by two consecutive tokens (sign+number)

<LI>compound terms in canonical notation are represented by two consecutive
    tokens (functor and opening parenthesis)

<LI>compound terms in operator syntax are represented by the operator's
    IDENTIFIER token

<LI>lists:
<P>
  a proper list [a,b] has subterms
	<PRE>
	[a,b]	represented by the [ token,
	[b]	represented by the , token,
	[]	represented by the ] token,
	a	represented by itself,
	b	represented by itself.
	</PRE>
  a general list [a,b|T] has subterms
	<PRE>
  	[a,b|T]	represented by the [ token,
  	[b|T]	represented by the , token,
  	T	represented by itself,
  	a	represented by itself,
  	b	represented by itself.
	</PRE>
  Note that the | and ] tokens do not represent any term.
</P>

<LI>special notations:
<P>
  {X}
<PRE>
	'{}'(X) represented by the { token,
	X	represented by itself
</PRE>
  X[Args]
<PRE>
	subscript(X, [...]) represented by the [ token,
	X,Args	represented by themselves
</PRE>
  X{Args}
<PRE>
  	'with attributes'(X,[Args]) represented by { token,
  	X,Args	represented by themselves
</PRE>
  a{Args}
<PRE>
	with(a,[Args])	represented by the { token
  	a,Args	represented by themselves
</PRE>
  X(Args)
<PRE>
  	apply(X,[Args])	represented by the ( token
  	X,Args	represented by themselves
</PRE>
</P>
</UL>
<P>
    Terms that were read from source may be subject to macro expansion
    (see macro/3, expand_macros/2).  In that case, term components
    that were introduced by the expansion may not have an exactly
    corresponding item in the source (but will usually inherit a
    meaningful, though not necessarily unique, source position). 
    Moreover, variables that were newly introduced by the expansion
    have a type-field of 'var' without name information.  Also,
    'anonymous' variables may have more than one occurrence after expansion.
</P><P>
    If only end of file is read, the event 190 is raised. The default
    handler unifies Term with an annotated term of the form
    annotated_term{term:end_of_file,type:end_of_file}, and the source
    location is the last position in the file.
</P><P>
    The default action for syntax errors is to print a warning and fail.
</P>

<H3>Modes and Determinism</H3><UL>
<LI>read_annotated(+, -, -) is semidet
</UL>
<H3>Modules</H3>
This predicate is sensitive to its module context (tool predicate, see @/2).
<H3>Fail Conditions</H3>
Fails if a syntax error was detected and no term could be read
<H3>Exceptions</H3>
<DL>
<DT><EM>(4) instantiation fault </EM>
<DD>Stream is not instantiated.
<DT><EM>(5) type error </EM>
<DD>Stream is not an atom or an integer.
<DT><EM>(190) end of file reached </EM>
<DD>End of file was encountered before reading any character.
<DT><EM>(192) illegal stream mode </EM>
<DD>Stream is not an input stream.
<DT><EM>(193) illegal stream specification </EM>
<DD>Stream is an illegal stream specification.
<DT><EM>(198) reading past the file end </EM>
<DD>Trying to read even after the error 190 was raised.
</DL>
<H2>Examples</H2>
<PRE>
?- read_annotated(input,T,AT).
 33.

T = 33
AT = annotated_term(33, integer, user, 1, 0, 2)
Yes (0.00s cpu)


?- read_annotated(input,T,AT).
 foo(bar).

T = foo(bar)
AT = annotated_term(foo(
	    annotated_term(bar, atom, user, 2, 8, 11)
	), compound, user, 2, 4, 8)
Yes (0.00s cpu)


?- read_annotated(input,X).
 a + 3.

T = a + 3
AT = annotated_term(
	    annotated_term(a, atom, user, 3, 14, 15)
	+   annotated_term(3, integer, user, 3, 18, 19),
	compound, user, 3, 16, 17)
Yes (0.00s cpu)


?- read_annotated(input,X).
 [a,b].

T = [a, b]
AT = annotated_term([
	    annotated_term(a, atom, user, 4, 22, 23)|
	    annotated_term([
		    annotated_term(b, atom, user, 4, 24, 25)|
		    annotated_term([], atom, user, 4, 25, 26)
		], compound, user, 4, 23, 24)
	], compound, user, 4, 21, 22)
Yes (0.00s cpu)
</PRE>
<H2>See Also</H2>
<A HREF="../../kernel/ioterm/read_annotated-2.html">read_annotated / 2</A>, <A HREF="../../kernel/ioterm/read-1.html">read / 1</A>, <A HREF="../../kernel/ioterm/readvar-3.html">readvar / 3</A>, <A HREF="../../kernel/iochar/read_token-2.html">read_token / 2</A>, <A HREF="../../kernel/iochar/read_token-3.html">read_token / 3</A>, <A HREF="../../kernel/ioterm/expand_macros-2.html">expand_macros / 2</A>, <A HREF="../../kernel/syntax/macro-3.html">macro / 3</A>, <A HREF="../../kernel/typetest/type_of-2.html">type_of / 2</A>
</BODY></HTML>
